# -*- coding: utf-8 -*-

from odoo import models, fields, api
import logging
import urllib
import urllib2
import json
import datetime
from odoo import time
import requests

_logger = logging.getLogger(__name__)

cert = ("/odoo/apps/wanlong/wliot/static/cert/client.crt",
        "/odoo/apps/wanlong/wliot/static/cert/client.key")


class wliotDevice(models.Model):
    _name = 'wliot.device'
    _inherit = ['mail.thread']

    # name = fields.Char()
    product_id = fields.Many2one('wliot.product', string=u'产品', required=True)
    device_id = fields.Char(string=u'IOT平台分配id')
    barcode = fields.Char(string=u'阀门追溯号', required=True)
    card_no = fields.Char(string=u'卡号', required=True)
    IMEI = fields.Char(string=u'IMEI号', required=True)
    status = fields.Selection([
        ('new', u'新建'),
        ('activited', u'激活'),
        ('installed', u'安装')
    ], string=u'状态', readonly=True)
    running_status = fields.Selection([
        ('normal', u'正常'),
        ('lostin', u'异常')
    ], string=u'运行状态', readonly=True)
    lostin = fields.Boolean(string=u'失联', readonly=True, default=False)
    outrange = fields.Boolean(string=u'超量程', readonly=True, default=False)
    alarm = fields.Boolean(string=u'报警', readonly=True, default=False)
    mode = fields.Selection([
        ('self', u'手动'),
        ('auto', u'自动')
    ], string=u'控制模式', readonly=True, default='self')
    ppm_sensor_id = fields.Many2one('wliot.ppm.sensor', string=u'传感器', readonly=True)
    partner_id = fields.Many2one('res.partner', string=u'客户', required=True)
    manufacture_date = fields.Date(string=u'出厂日期', required=True)
    install_date = fields.Date(string=u'安装日期')
    location = fields.Text(string=u'安装位置')
    self_open_degree = fields.Integer(string=u'手动开和度', readonly=True)
    auto_open_degree1 = fields.Integer(string=u'自动开合度', readonly=True)
    auto_open_degree2 = fields.Integer(string=u'自动开合度', readonly=True)
    auto_open_degree3 = fields.Integer(string=u'自动开合度', readonly=True)
    auto_open_degree4 = fields.Integer(string=u'自动开合度', readonly=True)
    auto_open_degree5 = fields.Integer(string=u'自动开合度', readonly=True)
    attribute_ids = fields.One2many('wliot.device.attribute', 'device', string=u'属性', readonly=True)
    indicator_value_ids = fields.One2many('wliot.device.indicator.value', 'device', string=u'设备当前值', readonly=True)
    indicator_log_ids = fields.One2many('wliot.device.indicator.log', 'device', string=u'设备数据日志', readonly=True)
    command_log_ids = fields.One2many('wliot.device.command.log', 'device', string=u'设备指令日志', readonly=True)
    maintain_record_ids = fields.One2many('wliot.device.maintain.record', 'device', string=u'设备维护记录', readonly=True)

    @api.multi
    def get_attributes(self):
        ''' 获取属性 '''
        self.ensure_one()
        attrs = self.env['wliot.device.attribute'].sudo().search([
            ('device', '=', self.id)
        ])
        attr_list = []
        for attr in attrs:
            a = {
                'id': attr.id,
                'description': attr.description
            }
            attr_list.append(a)
        return attr_list

    @api.multi
    def get_ppm_type(self):
        ''' 获取介质 '''
        self.ensure_one()
        product = self.get_product()
        ppm_type = self.env['wliot.ppm.type'].sudo().search([
            ('id', '=', product.ppm_type_id.id)
        ])
        return ppm_type.name

    @api.multi
    def get_product(self):
        ''' 获取产品 '''
        self.ensure_one()
        product = self.env['wliot.product'].sudo().search([
            ('id', '=', self.product_id.id)
        ])
        return product

    @api.multi
    def get_indicator_value(self):
        ''' 获取当前值 '''
        self.ensure_one()
        device_indicator_value = self.env['wliot.device.indicator.value'].sudo().search([
            ('device', '=', self.id)
        ])
        return device_indicator_value

    @api.multi
    def get_ppm_sensor(self):
        ''' 获取传感器 '''
        self.ensure_one()
        ppm_sensor = self.env['wliot.ppm.sensor'].sudo().search([
            ('id', '=', self.ppm_sensor_id.id)
        ])
        return ppm_sensor

    @api.multi
    def get_command_logs(self):
        ''' 获取命令日志 '''
        self.ensure_one()
        command_logs = self.env['wliot.device.command.log'].sudo().search([
            ('device', '=', self.id),
            ('order_type', '=', 'setting')
        ], order='code_time desc')
        logs = []
        for command_log in command_logs:
            logs.append(command_log.get_value())
        return logs

    @api.multi
    def get_maintain_logs(self):
        ''' 获取维修记录 '''
        self.ensure_one()
        maintain_logs = self.env['wliot.device.maintain.record'].sudo().search([
            ('device', '=', self.id)
        ])
        logs = []
        for maintain_log in maintain_logs:
            partner = self.env['res.partner'].sudo().search([
                ('id', '=', maintain_log.partner_id.id)
            ])
            logs.append({
                'partner': partner.name,
                'description': maintain_log.description,
                'time': maintain_log.time
            })
        return logs

    @api.multi
    def get_opendegree(self):
        ''' 获取开合度 '''
        self.ensure_one()
        if self.mode == 'self':
            return self.self_open_degree
        elif self.mode == 'auto':
            return [self.auto_open_degree1,
                    self.auto_open_degree2,
                    self.auto_open_degree3,
                    self.auto_open_degree4,
                    self.auto_open_degree5]

    @api.multi
    def get_control_logs(self):
        ''' 获取控制日志 '''
        self.ensure_one()
        control_logs = self.env['wliot.device.command.log'].sudo().search([
            ('device', '=', self.id),
            ('order_type', '=', 'control')
        ], order='code_time desc')
        logs = []
        for control_log in control_logs:
            if control_log.code == 4:
                opendegree = control_log.self_open_degree
            elif control_log.code == 6:
                opendegree = "%s,%s,%s,%s,%s" % (control_log.auto_open_degree_per20
                                                 , control_log.auto_open_degree_per40
                                                 , control_log.auto_open_degree_per60
                                                 , control_log.auto_open_degree_per80
                                                 , control_log.auto_open_degree_per100)
            if control_log.status == 'send':
                result = u'等待执行'
            elif control_log.status == 'work':
                result = u'执行成功'
            elif control_log.status == 'fail':
                result = u'执行失败'
            logs.append({
                'partner': control_log.partner_id.name,
                'opendegree': opendegree,
                'result': result,
                'code_time': control_log.code_time
            })
        return logs

    @api.multi
    def auth(self):
        ''' 鉴权 '''
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        secret = self.env['ir.config_parameter'].get_param('iot_secret')
        params = {
            'appId': app_id,
            'secret': secret
        }
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        response = requests.post(url="https://180.101.147.89:8743/iocm/app/sec/v1.1.0/login", data=params, cert=cert,
                                 verify=False, headers=headers)
        response = json.loads(response.text)
        access_token = response.get('accessToken')
        return access_token

    @api.multi
    def register_directly_connected_devices(self):
        ''' 注册直连设备 '''
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        access_token = self.auth()
        url = "https://180.101.147.89:8743/iocm/app/reg/v1.1.0/devices"
        params = {
            'verifyCode': self.IMEI,
            'nodeId': self.IMEI,
            'timeout': 0
        }

        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.post(url=url, data=json.dumps(params), cert=cert,
                                 verify=False, headers=headers)
        response = json.loads(response.text)
        self.device_id = response.get('deviceId')
        _logger.info(response)

    @api.multi
    def modify_device_info(self):
        ''' 修改设备信息 '''
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        access_token = self.auth()
        url = "https://180.101.147.89:8743/iocm/app/dm/v1.1.0/devices/%s" % self.device_id
        params = {
            'name': self.IMEI,
            'model': 'NBIoTDevice',
            'manufacturerId': 'Wanlong',
            'manufacturerName': 'Wanlong',
            'deviceType': 'Valve',
            'protocolType': 'CoAP',
            'location': 'CN'
        }
        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.put(url=url, data=json.dumps(params), cert=cert, verify=False, headers=headers)
        _logger.info(response)

    @api.multi
    def delete_directly_connected_device(self):
        ''' 删除直连设备 '''
        url = "https://wanlong.mxnet.cn/api/DeleteDirectlyConnectedDevice"
        data = {'deviceId': self.device_id}
        data = urllib.urlencode(data)
        req = urllib2.Request(url=url, data=data)
        res_data = urllib2.urlopen(req)
        res = json.loads(res_data.read())
        _logger.info(res)

    @api.multi
    def query_devices(self):
        ''' 查询单个设备信息 '''
        url = "https://wanlong.mxnet.cn/api/QueryDevices"
        # 可传可不传。传，单个信息；不传，列表信息
        data = {'deviceId': self.device_id}
        data = urllib.urlencode(data)
        req = urllib2.Request(url=url, data=data)
        res_data = urllib2.urlopen(req)
        res = json.loads(res_data.read())
        _logger.info(res)

    @api.multi
    def query_device_history_data(self):
        ''' 查询设备历史数据 '''
        url = "https://wanlong.mxnet.cn/api/QueryDeviceHistoryData"
        data = {'deviceId': self.device_id,
                'gatewayId': self.device_id}
        data = urllib.urlencode(data)
        req = urllib2.Request(url=url, data=data)
        res_data = urllib2.urlopen(req)
        res = json.loads(res_data.read())
        _logger.info(res)

    @api.multi
    def post_asyn_command_v4_1(self, **kw):
        ''' 创建设备命令 '''
        # openDegreeValue = kw.get('opendegree')
        # openDegreeValue = int(openDegreeValue)
        access_token = self.auth()
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        version = self.env['ir.config_parameter'].get_param('version')
        url = "https://180.101.147.89:8743/iocm/app/cmd/v1.4.0/deviceCommands?appId=%s" % app_id
        params = {
            'deviceId': self.device_id,
            'expireTime': 0,
            'command': {
                'serviceId': 'Switch',
                'method': 'SET_SELF_OPEN_DEGREE',
                'paras': {
                    'openDegreeValue': 10,
                    'modelNum': self.IMEI,
                    'time': '180827202756',
                    'codeID': 12345,
                    'cmdCode': 'selfOpenDegreeReq',
                    'version': version
                }
            }
        }
        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.post(url=url, data=json.dumps(params), cert=cert, verify=False, headers=headers)
        _logger.info(response.status_code)
        _logger.info(response.content)
        _logger.info(response.text)

    @api.multi
    def post_asyn_command_v4_2(self):
        ''' 创建设备命令 '''
        access_token = self.auth()
        version = self.env['ir.config_parameter'].get_param('version')
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        url = "https://180.101.147.89:8743/iocm/app/cmd/v1.4.0/deviceCommands?appId=%s" % app_id
        params = {
            'deviceId': self.device_id,
            'expireTime': 0,
            'command': {
                'serviceId': 'Switch',
                'method': 'SET_AUTO_OPEN_DEGREE',
                'paras': {
                    'openDegreeValue1': 10,
                    'openDegreeValue2': 30,
                    'openDegreeValue3': 50,
                    'openDegreeValue4': 70,
                    'openDegreeValue5': 90,
                    'modelNum': self.IMEI,
                    'time': '180827202756',
                    'codeID': 12345,
                    'cmdCode': 'autoOpenDegreeReq',
                    'version': version
                }
            }
        }
        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.post(url=url, data=json.dumps(params), cert=cert, verify=False, headers=headers)
        _logger.info(response.text)

    @api.multi
    def post_asyn_command_v4_3(self):
        ''' 创建设备命令 '''
        access_token = self.auth()
        version = self.env['ir.config_parameter'].get_param('version')
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        url = "https://180.101.147.89:8743/iocm/app/cmd/v1.4.0/deviceCommands?appId=%s" % app_id
        params = {
            'deviceId': self.device_id,
            'expireTime': 0,
            'command': {
                'serviceId': 'Setting',
                'method': 'SET_DEVICE',
                'paras': {
                    'frequencyValue': 10,
                    'alarmValue': 30,
                    'calibrationValue': 5,
                    'modelNum': self.IMEI,
                    'time': '180827202756',
                    'codeID': 12345,
                    'cmdCode': 'setDeviceReq',
                    'version': version
                }
            }
        }
        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.post(url=url, data=json.dumps(params), cert=cert, verify=False, headers=headers)
        _logger.info(response.text)

    @api.multi
    def post_asyn_command_v4_5(self):
        ''' 创建设备命令 '''
        access_token = self.auth()
        version = self.env['ir.config_parameter'].get_param('version')
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        url = "https://180.101.147.89:8743/iocm/app/cmd/v1.4.0/deviceCommands?appId=%s" % app_id
        params = {
            'deviceId': self.device_id,
            'expireTime': 0,
            'command': {
                'serviceId': 'Temperature',
                'method': 'CALIBRATE_TEMPERATURE',
                'paras': {
                    'temperatureValue': 2,
                    'modelNum': self.IMEI,
                    'time': '180827202756',
                    'codeID': 12345,
                    'cmdCode': 'temperatureReq',
                    'version': version
                }
            }
        }
        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.post(url=url, data=json.dumps(params), cert=cert, verify=False, headers=headers)
        _logger.info(response.text)

    @api.multi
    def discover_non_directly_connected_device(self):
        '''
            设备服务调用，为agent设备所用
        '''
        access_token = self.auth()
        app_id = self.env['ir.config_parameter'].get_param('iot_app_id')
        url = "https://180.101.147.89:8743/iocm/app/signaltrans/v1.1.0/devices/%s/services/%s/sendCommand?appId=%s" % (
            self.device_id, 'Switch', app_id)
        params = {
            'deviceId': self.device_id,
            'command': {
                'serviceId': 'Switch',
                'method': 'SET_SELF_OPEN_DEGREE',
                'paras': {
                    'openDegreeValue': 10
                }
            }
        }
        headers = {
            'app_key': app_id,
            'Authorization': 'Bearer %s' % access_token,
            'Content-Type': 'application/json'
        }
        response = requests.post(url=url, data=json.dumps(params), cert=cert, verify=False, headers=headers)
        _logger.info(response.text)

    @api.model
    def test_message(self, subject, subtype, partner_ids):
        device = self.search([('id', '=', 1)])
        device.send_message(subject, subtype, partner_ids)

    # -----设备异常触发消息--------------
    # subject:报警主题
    # subtype:消息类别
    # 1)失联：'wliot.mt_iot_losting'
    # partner_ids:相关联系人的Id列表
    # 例子：subject='ok', subtype='wliot.mt_iot_losting',partner_ids=[1]
    # ------------------------------
    @api.model
    def send_message(self, subject, subtype, partner_ids):
        '''发送通知'''
        p_ids = []
        # for partner_id in partner_ids:
        #     p_ids.append((partner_id,))
        # print p_ids
        self.message_subscribe(partner_ids=partner_ids)
        body = u"<p>%s</p ><a target='_blank' href='www.baidu.com'>111</ a>" % (subject)
        post_vars = {
            'body': body,
            'partner_ids': partner_ids,
        }
        self.message_post(message_type="notification", subtype=subtype, **post_vars)

    @api.multi
    def get_beijing_datetime(self, uploadtime):
        return (datetime.datetime.strptime(time.strftime('%Y-%m-%d',
                                                         time.localtime(int((long(uploadtime)) * (
                                                                 10 ** (10 - len(str(uploadtime))))))),
                                           '%Y-%m-%d') + datetime.timedelta(hours=8)).strftime(
            '%Y-%m-%d')

    @api.multi
    def test(self):
        t = self.get_beijing_datetime(1535938778000)
        _logger.info(t)
        t = self.get_string_time(t)
        _logger.info(t)

    @api.multi
    def get_string_time(self, bjtime):
        bjtime = str(bjtime)
        year = bjtime[2:4]
        month = bjtime[5:7]
        day = bjtime[8:10]
        hour = bjtime[11:13]
        minute = bjtime[14:16]
        second = bjtime[17:19]
        s = '%s\t%s\t%s\t%s\t%s\t%s' % (year, month, day, hour, minute, second)
        return s

    @api.multi
    def test_create_user(self):
        partners = self.env['res.partner'].sudo().search([])
        for partner in partners:
            user = self.env['res.users'].sudo().search([
                ('partner_id', '=', partner.id)
            ])
            if not user:
                self.env['res.users'].sudo().create({
                    'login': partner.phone if partner.phone else partner.mobile,
                    'partner_id': partner.id
                })
